/**      
* WebsgsAESOperator.java Create on 2012-11-18     
*      
* Copyright (c) 2012 by GreenShore Network
* Company: 上海绿岸网络科技有限公司(Shanghai GreenShore Network Technology Co.,Ltd.)
*
*/ 

package com.iwgame.websgs.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/** 
 * @ClassName: WebsgsAESOperator 
 * @Description: 加密/解密
 * @author caisheng
 * @date 2012-11-18 下午5:37:06 
 * @Version 1.0
 * 
 */
public class WebsgsAES {
	
	private static Logger log = LoggerFactory.getLogger(WebsgsAES.class);

	/**
   	 * 加密用的Key 可以用26个字母和数字组成
	 */
	private String sercurtyKey = "0123456789abcdef";

	/**
	 * 此处使用AES-128-CBC加密模式，key需要为16位。
	 */
	private byte[] ivParameter = "0123456789abcdef".getBytes();  //向量参数
	
	private static Cipher cipherObjForENcode;  //加密的Cipher对象
	private static Cipher cipherObjForDecode;  //解密的Cipher对象    
	
	private static BASE64Encoder base64Encode = new BASE64Encoder();
	private static BASE64Decoder base64Decoder = new BASE64Decoder();
	
	private static WebsgsAES instance = null;
	
	public static WebsgsAES getInstance(){
		if(null == instance){
			instance = new WebsgsAES();
		}
		return instance;
	}
	
	/**
	 * 构造方法:初始化需要的对象
	 */
	private WebsgsAES(){ 
		try {
			SecretKeySpec skeySpec = new SecretKeySpec(sercurtyKey.getBytes("ASCII"), "AES");
			IvParameterSpec iv = new IvParameterSpec(ivParameter);   //使用CBC模式，需要一个向量iv，可增加加密算法的强度
			
			//加密对象初始化
			cipherObjForENcode = Cipher.getInstance("AES/CBC/PKCS5Padding");
			cipherObjForENcode.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

			//解密对象初始化
			cipherObjForDecode = Cipher.getInstance("AES/CBC/PKCS5Padding");
			cipherObjForDecode.init(Cipher.DECRYPT_MODE, skeySpec, iv);
			System.out.println("----init-----");
		} catch (Exception e) {
			log.error("构造方法[加密/解密]错误.", e);
		}
	}

	/**
	 * 加密操作
	 * @param sourceCode 要加密的明文
	 * @return
	 * @throws Exception
	 */
	public String encrypt(String sourceCode){
		try{
			byte[] encrypted = cipherObjForENcode.doFinal(sourceCode.getBytes("utf-8"));
			return base64Encode.encode(encrypted);//此处使用BASE64做转码。
		}catch (Exception e) {
			log.error("加密错误。", e);
			return "";
		}
	}
	
	/**
	 * 解密操作
	 * @param sourceCode
	 * @return
	 * @throws Exception
	 */
	public String decrypt(String sourceCode){
		try {
			byte[] encrypted1 = base64Decoder.decodeBuffer(sourceCode);//先用base64解密
			byte[] original = cipherObjForDecode.doFinal(encrypted1);
			return new String(original,"utf-8");
		} catch (Exception e) {
			log.error("解密错误。", e);
			return "";
		}
	}
	
	public static void main(String[] args) {
		System.out.println(WebsgsAES.getInstance().encrypt("12"));
		System.out.println(WebsgsAES.getInstance().encrypt("12"));
		System.out.println(WebsgsAES.getInstance().encrypt("12"));
		System.out.println(WebsgsAES.getInstance().encrypt("12"));
		System.out.println(WebsgsAES.getInstance().encrypt("12"));
		
		System.out.println(WebsgsAES.getInstance().decrypt("RH16+u+/n2C6T4HArqSwYw=="));
	}
}
